package com.company.process.ds;

import com.company.graph.NopowerNoDirectEdgeWithNodeGraph;
import com.company.graph.PowerEdge;
import com.company.graphgetter.EdgeGetterWithGraph;
import com.company.process.GraphProcess;

import java.util.*;

public abstract class GraphDSProcess implements GraphProcess {

    int theta;
    NopowerNoDirectEdgeWithNodeGraph G;
    EdgeGetterWithGraph getter;
    Set<PowerEdge> e_plus = new HashSet<>();
    Set<PowerEdge> e_minus = new HashSet<>();
    HashMap<Integer, Integer> ET;

    public GraphDSProcess(int theta) {
        this.theta = theta;
        this.ET = new HashMap<>();
    }

    protected Integer getET(int id) {
        return ET.get(id);
    }

    protected Integer getRET(int id) {
        List<PowerEdge> relatedEdges = G.getRelatedEdges(id);
        if (relatedEdges == null) {
            return 0;
        }
        return relatedEdges.size() / 2;
    }

    protected void setET(int id, int etValue) {
        ET.put(id, etValue);
    }

    /**
     * 删除关联边
     *
     * @param bags        alpha的关联边
     * @param deleteCount alpha需要减少的“边三角个数”
     */
    protected void deleteRelatedEdgesWithBags(ArrayList<Bag> bags, int deleteCount) {
        int counter = 0;
        List<Integer> deleteList = new LinkedList<>();
        for (int i = 0; i < bags.size(); i += 2) {
            Bag bagA = bags.get(i);
            Bag bagB = bags.get(i + 1);
            int deleteId;
            if (bagA.getValue() < bagB.getValue()) {
                deleteId = bagA.getId();
            } else {
                deleteId = bagB.getId();
            }
            if (counter >= deleteCount) {
                break;
            }
            deleteList.add(deleteId);
            counter++;
        }
        for (Integer deleteId : deleteList) {
            G.deleteEdgeById(deleteId);
        }
    }

    /**
     * code forbidden
     * used before v1.3
     */
//    private int deleteRelated(int counter, List<Integer> deleteList, int deleteEdgeId) {
//        List<PowerEdge> deleteRelatedEdges = G.getRelatedEdges(deleteEdgeId);
//        if (deleteRelatedEdges != null) {
//            for (PowerEdge deleteRelatedEdge : deleteRelatedEdges) {
//                //让被删除边的关联边 完成DET的增加
//                increaseDET(deleteRelatedEdge.getId());
//            }
//            deleteList.add(deleteEdgeId);
//            ++counter;
//        }
//        return counter;
//    }

    public static class Bag implements Comparable<Bag> {
        int id;
        int value;

        public Bag(int id, int value) {
            this.id = id;
            this.value = value;
        }

        public static ArrayList<Bag> generateFromEdges(List<PowerEdge> relatedEdges, HashMap<Integer, Integer> ET) {
            ArrayList<Bag> list = new ArrayList<>();
            for (PowerEdge relatedEdge : relatedEdges) {
                int edgeId = relatedEdge.getId();
                list.add(new Bag(edgeId, ET.get(edgeId)));
            }
            return list;
        }


        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }


        @Override
        public int compareTo(Bag o) {
            return this.value - o.value;
        }
    }


}
